/**
 * 通用Web Worker包装器
 */
export class WorkerManager {
  constructor(workerScript) {
    this.worker = new Worker(workerScript);
    this.callbacks = new Map();
    this.messageId = 0;

    this.worker.onmessage = (e) => {
      const { id, error, result } = e.data;
      const callback = this.callbacks.get(id);
      if (callback) {
        if (error) callback.reject(error);
        else callback.resolve(result);
        this.callbacks.delete(id);
      }
    };
  }

  postMessage(message, transferables = []) {
    return new Promise((resolve, reject) => {
      const id = this.messageId++;
      this.callbacks.set(id, { resolve, reject });
      this.worker.postMessage({ id, message }, transferables);
    });
  }

  terminate() {
    this.worker.terminate();
    this.callbacks.forEach(({ reject }) => reject(new Error('Worker terminated')));
    this.callbacks.clear();
  }
}

/**
 * React Hook封装Web Worker
 */
export const useWebWorker = (workerScript) => {
  const workerRef = useRef();

  useEffect(() => {
    workerRef.current = new WorkerManager(workerScript);
    return () => workerRef.current.terminate();
  }, [workerScript]);

  const postMessage = useCallback((message) => {
    return workerRef.current?.postMessage(message);
  }, []);

  return postMessage;
};

/**
 * 创建基于Blob URL的Worker
 */
export const createInlineWorker = (workerFunc) => {
  const workerCode = `
    self.onmessage = async (e) => {
      const { id, message } = e.data;
      try {
        const result = await (${workerFunc.toString()})(message);
        self.postMessage({ id, result });
      } catch (error) {
        self.postMessage({ id, error: error.message });
      }
    };
  `;
  const blob = new Blob([workerCode], { type: 'application/javascript' });
  return new Worker(URL.createObjectURL(blob));
};
